/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iandtic.paydnie.dnie;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.smartcardio.*;

/**
 *
 * @author sergio
 */
public class DNIeConstructor {

    public DNIeConstructor() {}
    
    public DNIe setDNIeNIFandPIN(DNIe dnie, int pin){
        TerminalFactory factory = TerminalFactory.getDefault();
        List<CardTerminal> terminals = null;
        
        try {
            terminals = factory.terminals().list();
            // get terminal
            CardTerminal terminal = terminals.get(0);
            Card c=terminal.connect("*"); //T=0, T=1 or T=CL(not needed)
            CardChannel ch = c.getBasicChannel();
            dnie.setNIF(readFromCertificate(ch));
            dnie.setPIN(pin);
            c.disconnect(false);

        } catch (Exception ex) {
            Logger.getLogger(DNIe.class.getName()).log(Level.SEVERE, null, ex);
        }
        return dnie;
    }
    
        
   public String readFromCertificate(CardChannel ch) throws CardException {
        int offset = 0;
        String dnieNIF = null;
       
        byte[] command = new byte[] {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x0b, (byte)0x4D, (byte)0x61, (byte)0x73, (byte)0x74, (byte)0x65, (byte)0x72, (byte)0x2E, (byte)0x46, (byte)0x69, (byte)0x6C, (byte)0x65};
        ResponseAPDU r = ch.transmit(new CommandAPDU(command));
        if( (byte)r.getSW() != (byte)0x9000){
            System.out.println("SW incorrecto");
            return null;
        }

        //Seleccionamos el directorio PKCS#15 5015
        command = new byte[] {(byte)0x00, (byte)0xA4, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x50, (byte)0x15};
        r = ch.transmit(new CommandAPDU(command));
   
        if( (byte)r.getSW() != (byte)0x9000){
            System.out.println("SW incorrecto");
            return null;
        }

        //Seleccionamos el Certificate Directory File (CDF) del DNIe 6004
        command = new byte[] {(byte)0x00, (byte)0xA4, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x60, (byte)0x04};
        r = ch.transmit(new CommandAPDU(command));

        if( (byte)r.getSW() != (byte)0x9000){
            System.out.println("SW incorrecto");
            return null;
        }

        //Leemos FF bytes del archivo
        command = new byte[] {(byte)0x00, (byte)0xB0, (byte)0x00, (byte)0x00, (byte)0xFF};
        r = ch.transmit(new CommandAPDU(command));


        if( (byte)r.getSW() == (byte)0x9000){
            byte[] r2 = r.getData();

            if(r2[4]==0x30){
                offset=4;
                offset += r2[offset+1]+2; //Obviamos la seccion del Label
            }

            if(r2[offset]==0x30){
                offset += r2[offset+1]+2; //Obviamos la seccion de la informacion sobre la fecha de expedición etc
            }

            if ( (byte)r2[offset] == (byte) 0xA1){
                //El certificado empieza aquí
                byte[] r3 = new byte[9];
                
                //Nos posicionamos en el byte donde empieza el NIF y leemos sus 9 bytes
                for(int z=0; z<9; z++){
                    r3[z] = r2[109+z];
                }
                dnieNIF = new String(r3);
            }
        }        
        return dnieNIF;
    }
    
    
}
